package com.swallow.auth.domain.uniqno;

import com.swallow.auth.common.constants.RedisConstants;
import com.swallow.auth.common.utils.SpringUtils;
import com.swallow.auth.domain.uniqno.model.entity.BizNoValObj;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author: yangjie.deng@resico.cn
 * @since: 2024-04-03 15:12:37
 * @version: v1.0.0
 * @describe: 分布式唯一主键生成器
 */
@SuppressWarnings("unchecked")
public class NumWorker {
    private static final RedisTemplate<String, String> redisTemplate;
//    private static final INumRepository numRepository;

    static {
        // 2 + 8 + 8
        redisTemplate = SpringUtils.getBean("stringRedisTemplate", RedisTemplate.class);
//        numRepository = SpringUtils.getBean(INumRepository.class);
    }

    private static String uniqNo(BizNoValObj bizEnum) {
        RedisAtomicLong atomic = new RedisAtomicLong(RedisConstants.UNIQUE_ID_KEY.formatted(bizEnum.getBizFlag()),
                                                     Objects.requireNonNull(redisTemplate.getConnectionFactory()));

        if (Objects.nonNull(atomic.getExpire()) && atomic.getExpire() == -1) {
            atomic.expire(5, TimeUnit.DAYS);
        }
        return StringUtils.leftPad(String.valueOf(atomic.getAndIncrement()), 8, "0");
    }

    public static String bizNo() {
        return bizNo(BizNoValObj.DEFAULT_NO);
    }

    public static String bizNo(BizNoValObj bizNoEnum) {
        Integer bizNo = bizNoEnum.getValue();
        String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String bizId;
        try {
            bizId = uniqNo(bizNoEnum);
        } catch (Exception e) {
            bizId = uniqNoFromDB(bizNoEnum);
        }

        return String.valueOf(bizNo).concat(date).concat(bizId);
    }

    private static String uniqNoFromDB(BizNoValObj bizNoEnum) {
        /*long num = numRepository.getNum(bizNoEnum);*/
        return StringUtils.leftPad(String.valueOf(100), 8, "0");
    }
}
